{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "# 在线性回归模型中使用梯度下降法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "np.random.seed(666)\n",
    "x = 2 * np.random.random(size=100)\n",
    "y = x * 3. + 4. + np.random.normal(size=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 1.40087424,  1.68837329,  1.35302867,  1.45571611,  1.90291591,\n        0.02540639,  0.8271754 ,  0.09762559,  0.19985712,  1.01613261,\n        0.40049508,  1.48830834,  0.38578401,  1.4016895 ,  0.58645621,\n        1.54895891,  0.01021768,  0.22571531,  0.22190734,  0.49533646,\n        0.0464726 ,  1.45464231,  0.68006988,  0.39500631,  1.81835919,\n        1.95669397,  1.06560509,  0.5182637 ,  1.16762524,  0.65138131,\n        1.77779863,  1.25280905,  1.63774738,  1.09469084,  0.83342401,\n        1.48609438,  0.73919276,  0.15033309,  1.55038596,  0.43881849,\n        0.15868425,  0.97356104,  0.3073478 ,  1.65693027,  0.38273714,\n        0.54081791,  1.12206884,  1.80476078,  1.70357668,  0.83616392,\n        0.78695254,  0.03244103,  0.59842674,  0.70755644,  1.78700533,\n        1.57227314,  1.54277385,  0.84010971,  1.55205028,  0.92861629,\n        0.36354033,  1.76805121,  1.43758454,  1.3437626 ,  0.51312727,\n        0.86160364,  0.03290715,  0.46998765,  1.02234262,  0.58401848,\n        1.00378702,  0.99654626,  0.20754305,  0.89288623,  1.93837834,\n        1.47694224,  1.43910122,  1.78608677,  1.92534936,  0.39410046,\n        1.42917993,  0.32384788,  1.73250954,  1.24764049,  1.91891025,\n        1.04828408,  0.07286576,  1.45374316,  0.00781969,  0.100588  ,\n        1.98398463,  0.424515  ,  1.89474133,  0.9030811 ,  1.99758935,\n        1.29500298,  1.40448142,  0.85916353,  0.33554952,  0.23626619])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([  8.91412688,   8.89446981,   8.85921604,   9.04490343,\n         8.75831915,   4.01914255,   6.84103696,   4.81582242,\n         3.68561238,   6.46344854,   4.61756153,   8.45774339,\n         3.21438541,   7.98486624,   4.18885101,   8.46060979,\n         4.29706975,   4.06803046,   3.58490782,   7.0558176 ,\n         4.04787249,   7.46699513,   7.17356576,   6.90706602,\n        10.06445574,  10.46043335,   6.56186893,   7.41768066,\n         6.63306338,   5.16962652,   8.92568927,   8.81142811,\n         8.27497363,   9.55931293,   8.31763691,   8.39594229,\n         6.46897919,   4.53407649,   9.01364797,   5.23131871,\n         5.35968048,   4.92858955,   4.86197655,   8.18778792,\n         3.53458796,   3.82545342,   7.06040408,  10.08420404,\n        10.5135845 ,   5.57993775,   6.63546582,   2.56719372,\n         6.94786703,   5.21927087,   9.54664436,   8.92205488,\n         9.1083202 ,   7.66433039,   8.04596666,   7.0692907 ,\n         6.52268065,   8.89229807,  11.53002966,   6.91636019,\n         4.88098465,   6.9583948 ,   2.97055168,   5.2614817 ,\n         5.8844378 ,   5.04227386,   4.25122982,   7.27271509,\n         5.71044451,   6.78615502,   9.60686078,   7.76422413,\n         7.66241623,  10.79248261,   9.42339386,   4.16563131,\n         8.90109862,   4.78925295,   9.51168702,   8.62159339,\n         9.32966334,   8.06523273,   5.25671307,   8.81165672,\n         6.08431894,   4.74245033,   8.29671129,   6.90839908,\n        10.42354245,   5.65267702,  10.16017935,   9.02635276,\n         6.94102685,   6.27077412,   6.77410495,   3.92117584])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 转换为100行，1列的数据\n",
    "X = x.reshape(-1,1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1064a0ba8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x,y)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 使用梯度下降训练法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 定义一个损失函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def J(theta, X_b, y):\n",
    "    \"\"\"\n",
    "    给定θ，特征矩阵X，标记向量y，根据损失函数得出其（损失）值\n",
    "    :param theta: \n",
    "    :param X_b: \n",
    "    :param y: \n",
    "    :return: \n",
    "    \"\"\"\n",
    "    \n",
    "    # 分子部分其实等价于 (y - X_b.dot(theta)).T.dot(y - X_b.dot(theta))\n",
    "    try:\n",
    "        return np.sum((y - X_b.dot(theta))**2) / len(X_b)\n",
    "    except:\n",
    "        return float('inf') #防止溢出？有异常直接返回最大值\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 损失函数J的梯度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def derivative_J(theta:np.ndarray, X_b:np.ndarray, y:np.ndarray):\n",
    "    \"\"\"\n",
    "    求θ为给定值时的导数\n",
    "    :param theta: \n",
    "    :param X_b: \n",
    "    :param y: \n",
    "    :return: \n",
    "    \"\"\"\n",
    "    res = np.empty(len(theta))\n",
    "    res[0] = np.sum(X_b.dot(theta) - y)\n",
    "    for i in range(1, len(theta)):\n",
    "        res[i] = (X_b.dot(theta) - y).dot(X_b[:,i])\n",
    "    return res * 2 / len(X_b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 梯度下降的方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "def gradient_descent(X_b, y, initial_theta, eta, n_iters=1e4, epsilon=1e-8):\n",
    "    theta = initial_theta\n",
    "    iters = 0\n",
    "    while iters < n_iters:\n",
    "        gradient = derivative_J(theta, X_b, y)\n",
    "        last_theta = theta\n",
    "        theta = theta - eta*gradient\n",
    "        \n",
    "        if (abs(J(theta, X_b, y) - J(last_theta, X_b, y)) < epsilon):\n",
    "            break\n",
    "        iters += 1\n",
    "    return theta"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 看看梯度下降的效果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_b = np.hstack((np.ones((len(x),1)),X))\n",
    "initial_theta = np.zeros(X_b.shape[1])  # 初始的θ向量都是0\n",
    "eta = 0.01  # 学习率\n",
    "\n",
    "theta = gradient_descent(X_b, y, initial_theta, eta)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 4.02145786,  3.00706277])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "theta"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "跟上边y = x * 3. + 4. + np.random.normal(size=100)的系数3 和截距4 结果很接近"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 测试我们刚刚封装好的线性回归算法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LinearRegression()"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from playML.linear_regression import LinearRegression\n",
    "\n",
    "lin_reg = LinearRegression()\n",
    "lin_reg.fit_gd(X, y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 3.00706277])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lin_reg.coef_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4.021457858204859"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lin_reg.interception_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
